/*
 * board.js
 * http://dev.akinao.com/
 */
//@require akinao/name.js
//@require akinao/lang.js
akinao.namespace('game');
(function(){

	var Lang = akinao.lang;

	function Point(x, y) {
		this.x = x;
		this.y = y;
	}

	Point.UP = new Point(0, -1);
	Point.DOWN = new Point(0, 1);
	Point.RIGHT = new Point(1, 0);
	Point.LEFT = new Point(-1, 0);
	Point.DIR4 = [Point.UP, Point.RIGHT, Point.DOWN, Point.LEFT];

	Point.prototype.add = function(a, b) {
		if (Lang.isUndefined(b)) {
			return new Point(this.x + a.x, this.y + a.y);
		} else {
			return new Point(this.x + a, this.y + b);
		}
	};

	Point.prototype.subtract = function(a, b) {
		if (Lang.isUndefined(b)) {
			return new Point(this.x - a.x, this.y - a.y);
		} else {
			return new Point(this.x - a, this.y - b);
		}
	};

	Point.prototype.multiply = function(number) {
		return new Point(this.x * number, this.y * number);
	};

	Point.prototype.divide = function(number) {
		return new Point(this.x / number, this.y / number);
	};

	Point.prototype.dir4 = function() {
		return [new Point(this.x, this.y - 1),
				new Point(this.x + 1, this.y),
				new Point(this.x, this.y + 1),
				new Point(this.x - 1, this.y)];
	};

	Point.prototype.clone = function() {
		return new Point(this.x, this.y);
	};

	Point.prototype.equals = function(point) {
		return this.x == point.x && this.y == point.y;
	};

	/*
	 * size,value
	 * Point,value
	 * x,y,value
	 */
	function Board(a, b, c){
		var value;
		if (Lang.isUndefined(c)) {
			if (Lang.isUndefined(a.x)) {
				this.size = new Point(a, a);
			} else {
				this.size = a;
			}
			value = b;
		} else {
			this.size = new Point(a, b)
			value = c;
		}
		this.map = [];
		for (var i = 0; i < this.size.x; i++) {
			this.map[i] = [];
			for (var j = 0; j < this.size.y; j++) {
				this.map[i][j] = value;
			}
		}
	}

	Board.prototype.get = function(a, b) {
		if (Lang.isUndefined(b)) {
			return this.map[a.x][a.y];
		} else {
			return this.map[a][b];
		}
	};

	Board.prototype.set = function(value, a, b) {
		if (Lang.isUndefined(b)) {
			this.map[a.x][a.y] = value;
		} else {
			this.map[a][b] = value;
		}
	};

	Board.prototype.clear = function(value) {
		for (var i = 0; i < this.map.length; i++) {
			for (var j = 0; j < this.map[i].length; j++) {
				this.map[i][j] = value;
			}
		}
	};

	Board.prototype.isOut = function(point) {
		return 0 > point.x || 0 > point.y || this.size.x <= point.x || this.size.y <= point.y;
	};

	Board.prototype.size = function() {
		return this.size;
	};

	function PointMap() {
		this._value = {};
	}

	PointMap.prototype.get = function(a, b) {
		var key = toKey(a, b);
		return this._value[key];
	};

	PointMap.prototype.set = function(value, a, b) {
		var key = toKey(a, b);
		return this._value[key] = value;
	};

	function toKey(a, b) {
		if (Lang.isUndefined(b)) {
			return "" + a.x + "-" + a.y;
		} else {
			return "" + a + "-" + b;
		}
	}

	akinao.game.Point = Point;
	akinao.game.PointMap = PointMap;
	akinao.game.Board = Board;
})();
